﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using LuaInterface;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
using System.Threading;

namespace PrgMonitor
{
	public partial class PrgMonitorService : ServiceBase
	{
		[DllImport("user32.dll")]
		public static extern IntPtr GetForegroundWindow();
		[DllImport("user32.dll")]
		public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
		[DllImport("user32.dll")]
		public static extern int GetWindow(IntPtr hWnd, int wCmd);
		[DllImport("user32.dll")]
		public static extern int GetWindowTextLength(IntPtr hWnd);
		[DllImport("user32.dll")]
		public static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount);

		/// <summary>
		/// lua虚拟机
		/// </summary>
		private static Lua luaVM = null;

		FileSystemWatcher watcher;
		private bool bIsReLoadLua = false;

		//定时器
		System.Timers.Timer tmAutoChk;
	
		public PrgMonitorService()
		{
			InitializeComponent();
		}

		protected override void OnStart(string[] args)
		{
			LuaInit();	//lua脚本初始化

			this.tmAutoChk = new System.Timers.Timer(10000);
			this.tmAutoChk.Elapsed += new System.Timers.ElapsedEventHandler(tmAutoChkEvent);
			this.tmAutoChk.Enabled = true;
		}

		protected override void OnStop()
		{
		}

		/// <summary>
		/// lua初始化
		/// </summary>
		private void LuaInit()
		{
			try
			{
				Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);

				luaVM = new Lua();

				//为脚本提供操作进程的方法
				luaVM.RegisterFunction("luaSkillProcessesByName", null, typeof(PrgMonitorService).GetMethod("luaSkillProcessesByName"));
				luaVM.RegisterFunction("luaSkillProcessesById", null, typeof(PrgMonitorService).GetMethod("luaSkillProcessesById"));
				luaVM.RegisterFunction("luaStartProcessByName", null, typeof(PrgMonitorService).GetMethod("luaStartProcessByName"));
				luaVM.RegisterFunction("luaGetProcesseNumByName", null, typeof(PrgMonitorService).GetMethod("luaGetProcesseNumByName"));
				luaVM.RegisterFunction("luaStopServiceByName", null, typeof(PrgMonitorService).GetMethod("luaStopServiceByName"));
				luaVM.RegisterFunction("luaStartServiceByName", null, typeof(PrgMonitorService).GetMethod("luaStartServiceByName"));
				luaVM.RegisterFunction("luaGetProcesseCPUByName", null, typeof(PrgMonitorService).GetMethod("luaGetProcesseCPUByName"));
				
				if (File.Exists("lua/timerservice.lua"))
				{
					luaVM.DoFile("lua/timerservice.lua");
				}

				//监视lua目录
				watcher = new FileSystemWatcher();
				watcher.Path = "lua";
				watcher.NotifyFilter = NotifyFilters.LastWrite;
				watcher.Filter = "*.lua";
				watcher.Changed += new FileSystemEventHandler(OnLuaChanged);

				watcher.EnableRaisingEvents = true;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " LuaInit " + ex.Message);
			}
		}

		private void OnLuaChanged(object source, FileSystemEventArgs e)
		{
			//LogAPI.WriteLog(String.Format("LuaChanged：{0} {1}！", e.FullPath, e.ChangeType));
			this.bIsReLoadLua = true;
		}

		/// <summary>
		/// 自动检查定时器
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tmAutoChkEvent(object sender, System.Timers.ElapsedEventArgs e)
		{
			this.tmAutoChk.Enabled = false;

			//重载脚本
			if (this.bIsReLoadLua)
			{
				this.bIsReLoadLua = false;
				LogAPI.WriteLog("脚本变化，重新加载");
				try
				{
					if (File.Exists("lua/timerservice.lua"))
					{
						luaVM.DoFile("lua/timerservice.lua");	//处理的脚本
					}
				}
				catch (Exception ex)
				{
					LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.LuaLoadFile " + ex.Message);
				}
			}

			try
			{
				LuaFunction luaFun = null;
				luaFun = luaVM.GetFunction("luaOnTimer");
				if (luaFun != null)
				{
					lock (luaVM)
					{
						try
						{
							object[] retVals = luaFun.Call();
						}
						catch (Exception ex)
						{
							LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.ExecLua " + ex.Message);
						}
					}
				}
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " tmAutoChkEvent.GetFunction " + ex.Message);
			}

			this.tmAutoChk.Enabled = true;
		}

		/// <summary>
		/// 通过名称查找进程
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		private static Process FindProcessesByName(string sProcessName)
		{
			try
			{
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.ProcessName == sProcessName)
					{
						return item;
					}
				}
				return null;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " FindProcessesByName " + ex.Message);
				return null;
			}
		}

		/// <summary>
		/// 通过进程ID查找进程
		/// </summary>
		/// <param name="iProcessId"></param>
		/// <returns></returns>
		private static Process FindProcessesById(int iProcessId)
		{
			try
			{
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.Id == iProcessId)
					{
						return item;
					}
				}
				return null;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " FindProcessesById " + ex.Message);
				return null;
			}
		}


		/// <summary>
		/// 提供给脚本，结束进程
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static bool luaSkillProcessesByName(string sProcessName)
		{
			try
			{
				Process item = FindProcessesByName(sProcessName);
				if (item != null)
				{
					item.Kill();
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaSkillProcessesByName " + ex.Message);
				return false;
			}
		}

		public static bool luaSkillProcessesById(int iProcessId)
		{
			try
			{
				Process item = FindProcessesById(iProcessId);
				if (item != null)
				{
					item.Kill();
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaSkillProcessesById " + ex.Message);
				return false;
			}
		}

		public static bool luaStartProcessByName(string sProcessName)
		{
			try
			{
				ProcessExtensions.StartProcessAsCurrentUser(sProcessName);
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaStartProcessByName " + ex.Message);
				return false;
			}
			return true;
		}

		/// <summary>
		/// 根据进程名字获得进程数量
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static int luaGetProcesseNumByName(string sProcessName)
		{
			try
			{
				int iNum = 0;
				Process[] ps = Process.GetProcesses();
				foreach (Process item in ps)
				{
					if (item.ProcessName == sProcessName)
					{
						iNum++;
					}
				}
				return iNum;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaGetProcesseNumByName " + ex.Message);
				return 0;
			}
		}

		/// <summary>
		/// 停止指定的服务
		/// </summary>
		/// <param name="sServiceName"></param>
		public static void luaStopServiceByName(string sServiceName)
		{
			try
			{
				ServiceController sc = new ServiceController(sServiceName);
				if (sc.Status.Equals(ServiceControllerStatus.Running))
				{
					sc.Stop();
					sc.Refresh();
					LogAPI.WriteLog("服务 " + sServiceName + " 停止");
				}
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaStopServiceByName " + ex.Message);
			}
		}

		/// <summary>
		/// 启动指定的服务
		/// </summary>
		/// <param name="sServiceName"></param>
		public static void luaStartServiceByName(string sServiceName)
		{
			try
			{
				ServiceController sc = new ServiceController(sServiceName);
				if (sc.Status.Equals(ServiceControllerStatus.Stopped))
				{
					sc.Start();
					sc.Refresh();
					LogAPI.WriteLog("服务 " + sServiceName + " 启动");
				}
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaStartServiceByName " + ex.Message);
			}
		}

		/// <summary>
		/// 获得进程的CPU占用率
		/// </summary>
		/// <param name="sProcessName"></param>
		/// <returns></returns>
		public static int luaGetProcesseCPUByName(string sProcessName)
		{
			try
			{
				Process item = FindProcessesByName(sProcessName);
				if (item != null)
				{
					PerformanceCounter pp = new PerformanceCounter();//性能计数器
					pp.CategoryName = "Process";
					pp.CounterName = "% Processor Time";
					pp.InstanceName = sProcessName;			//指定进程 
					pp.MachineName = ".";
					pp.NextValue();
					Thread.Sleep(1100);
					return (int)pp.NextValue();
				}
				return -1;
			}
			catch (Exception ex)
			{
				LogAPI.WriteLog(ex.Source + " luaGetProcesseCPUByName " + ex.Message);
				return 0;
			}
		}
	}
}
